package cas.ihep.fs;

import cas.ihep.fs.impl.CreateOptionsImpl;
import cas.ihep.fs.impl.OpenOptionImpl;
import cas.ihep.fs.impl.UnifiedConf;
import cas.ihep.fs.impl.UnifiedFileSystemImpl;
import com.google.common.io.Closer;
import org.apache.hadoop.hdfs.DFSClient;

import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.URI;
import java.util.Map;

public abstract class UnifiedFileSystem implements UnifiedAbstractFileSystem{

    public interface CreateOptions {
        boolean overwrite();
        boolean createParent();
        short replication();
        short permission();
        long blockSize();
        int bufferSize();

        void setOverwrite(boolean overwrite);
        void setCreateParent(boolean createParent);
        void setReplication(short replication);
        void setPermission(short permission);
        void setBlockSize(long blockSize);
        void setBufferSize(int bufSize);
    }

    public interface OpenOptions {

    }

    public interface AppendOptions extends CreateOptions {
    }

    public interface Configuration extends Map<String,Object> {
        int getInt(String key);
        String getString(String key);
        boolean getBoolean(String key);
        int getInt(String key,int defVal);
        String getString(String key,String defVal);
        boolean getBoolean(String key,boolean defVal);
        org.apache.hadoop.conf.Configuration hadoopConf();
    }

    public static UnifiedFileSystem get(Configuration conf){
        return new UnifiedFileSystemImpl(conf);
    }
    public static CreateOptions defaultCreateOptions(){
        return new CreateOptionsImpl();
    }
    public static OpenOptions defaultOpenOptions(){return new OpenOptionImpl();}
    public static AppendOptions defaultAppendOptions(){return new CreateOptionsImpl.AppendOptionsImpl();}
    public static Configuration newConfiguration(org.apache.hadoop.conf.Configuration conf){return new UnifiedConf(conf);}
    public static Configuration newConfiguration(String hadoopHome){
        org.apache.hadoop.conf.Configuration conf=new org.apache.hadoop.conf.Configuration();
        final Closer closer=Closer.create();
        try{
            conf.addResource(closer.register(new FileInputStream(hadoopHome+"/etc/hadoop/core-site.xml")));
            conf.addResource(closer.register(new FileInputStream(hadoopHome+"/etc/hadoop/hdfs-site.xml")));
            Runtime.getRuntime().addShutdownHook(new Thread(){
                public void run(){
                    try {
                        closer.close();
                    }catch (IOException ignored){}
                }
            });
        }catch (IOException ignored){}
        return UnifiedConf.newConf(conf);
    }

    public abstract DFSClient dfsClient();
    public abstract org.apache.hadoop.fs.FileSystem hdfsSystem();
    public abstract alluxio.client.file.FileSystem alluxioFileSystem();
    public abstract UnifiedFile open(URI uri)throws IOException;
    public abstract UnifiedFile create(URI uri)throws IOException;
    public abstract void mkdir(URI uri)throws IOException;
    public abstract InputStream openStream(URI uri)throws IOException;
    public abstract OutputStream createStream(URI uri)throws IOException;
}
